package com.brillilab.service.core.lab.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.brillilab.dao.mapper.lab.LabMemberPowerMapper;
import com.brillilab.domain.enums.lab.LabEnum;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum.Power;
import com.brillilab.domain.enums.lab.UserEnum;
import com.brillilab.domain.pa.lab.PowerModifyPa;
import com.brillilab.domain.po.lab.Lab;
import com.brillilab.domain.po.lab.LabMember;
import com.brillilab.domain.po.lab.LabMemberPower;
import com.brillilab.domain.po.user.Users;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.lab.ILabMemberPowerService;
import com.brillilab.service.core.lab.ILabMemberService;
import com.brillilab.service.core.lab.ILabService;
import com.brillilab.service.core.user.IUsersService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Transactional
public class LabMemberPowerServiceImpl implements ILabMemberPowerService {

	@Resource
	private LabMemberPowerMapper labMemberPowerMapper;
	@Resource
	private ILabMemberService labMemberService;
	@Resource
	private IUsersService usersService;
	@Resource
	private ILabService labService;

	@Override
	public List<LabMemberPower> selectList(Long labId, Long labMemberId) {
		boolean isOwner = labMemberService.isOwner(labId, labMemberId);
		if(isOwner){
			List<LabMemberPower> list = new ArrayList<>();
			Power[] powers = LabMemberPowerEnum.Power.values();
			for (Power power : powers) {
				LabMemberPower labMemberPower =  new LabMemberPower();
				labMemberPower.setLabId(labId);
				labMemberPower.setLabMemberId(labMemberId);
				labMemberPower.setPower(power.getValue());
				list.add(labMemberPower);
			}
			return list;
		}else{
			LambdaQueryWrapper<LabMemberPower> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(LabMemberPower::getLabId, labId);
			wrapper.eq(LabMemberPower::getLabMemberId, labMemberId);
			return labMemberPowerMapper.selectList(wrapper);
		}
	}

	@Override
	public LabMemberPower add(LabMemberPower entity) {
		Assert.isTrue(LabMemberPowerEnum.Power.getKey(entity.getPower()) != null, "参数错误");

		LambdaQueryWrapper<LabMemberPower> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(LabMemberPower::getLabId, entity.getLabId());
		wrapper.eq(LabMemberPower::getLabMemberId, entity.getLabMemberId());
		wrapper.eq(LabMemberPower::getPower, entity.getPower());
		LabMemberPower power = labMemberPowerMapper.selectOne(wrapper);
		if (power == null) {
			int b = labMemberPowerMapper.insert(entity);
			return b == 1 ? entity : null;
		}
		return power;
	}

	@Override
	@Transactional
	public boolean modifyOne(Long labId, Long labMemberId, String power, Integer isOpen) {

		boolean flag = false;

		if (isOpen == 1) {
			this.delete(labId, labMemberId, power);
			LabMemberPower entity = new LabMemberPower();
			entity.setLabId(labId);
			entity.setLabMemberId(labMemberId);
			entity.setPower(power.trim());
			this.add(entity);
			if (entity.getId() != null) {
				flag = true;
			}
		} else if (isOpen == 0) {
			flag = this.delete(labId, labMemberId, power);
		}
		return flag;
	}

	@Override
	public boolean delete(Long id) {
		int b = labMemberPowerMapper.deleteById(id);
		return b == 1;
	}

	@Override
	public boolean delete(Long labId, Long labMemberId, String power) {
		Assert.isTrue(LabMemberPowerEnum.Power.getKey(power) != null, "参数错误");

		LambdaQueryWrapper<LabMemberPower> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(LabMemberPower::getLabId, labId);
		wrapper.eq(LabMemberPower::getLabMemberId, labMemberId);
		wrapper.eq(LabMemberPower::getPower, power);

		LabMemberPower memberPower = labMemberPowerMapper.selectOne(wrapper);
		if (memberPower == null) {
			return true;
		}
		int b = labMemberPowerMapper.deleteById(memberPower.getId());
		return b == 1;
	}

	@Override
	public boolean deleteAll(Long labId, Long labMemberId) {
		LambdaQueryWrapper<LabMemberPower> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(LabMemberPower::getLabId, labId);
		wrapper.eq(LabMemberPower::getLabMemberId, labMemberId);

		List<LabMemberPower> list = labMemberPowerMapper.selectList(wrapper);
		if (list == null || list.size() == 0) {
			return true;
		}
		int b = labMemberPowerMapper.delete(wrapper);
		return b > 0;
	}

	@Transactional
	@Override
	public boolean modifyPower(Long labId, Long labMemberId, String[] powers) {

		List<String> powerList = Arrays.asList(powers);
		// 先删除原有权限，在添加权限
		boolean vo = this.deleteAll(labId, labMemberId);
		Assert.isTrue(vo, "修改失败");

		if (powers != null && powerList.size() > 0) {
			LabMemberPower entity = null;
			for (String power : powerList) {
				if (LabMemberPowerEnum.Power.getKey(power) != null) {
					entity = new LabMemberPower();
					entity.setLabId(labId);
					entity.setLabMemberId(labMemberId);
					entity.setPower(power.trim());
					this.add(entity);
					Assert.notNull(entity.getId(), "修改失败");
				}
			}
		}
		return true;
	}

	public boolean isOwner(Long labId, Long labMemberId) {
		Users users = usersService.selectUser(labId, labMemberId, UserEnum.State.NORMAL.getValue());
		Assert.notNull(users, "用户状态异常");
		Lab lab = labService.selectById(labId);
		Assert.isTrue(lab != null && lab.getState().equals(LabEnum.State.NORMAL.getValue()), "实验室不存在！");
		return lab.getOwnerId().equals(users.getId());
	}

	
	@Override
	@Transactional
	public boolean batchModifyPower(UserInfoVo userInfo, List<PowerModifyPa> reqList) {
		
		if (reqList != null && reqList.size() > 0) {
			String power = reqList.get(0).getPower();
			// 用户管理权限只能由实验室管理员授权
			if (power.equals(LabMemberPowerEnum.Power.USER_MANAGE.getValue())) {
				Assert.isTrue(userInfo.getId().equals(userInfo.getOwnerId()), "您不能操作用户管理权限！");
			}
			List<Long> labMemberIdAll = new ArrayList<>();
			List<Long> labMemberIdOpen = new ArrayList<>();
			// 获取实验室所有者实验室成员信息
			LabMember adminMember = labMemberService.selectMember(userInfo.getLabId(), userInfo.getOwnerId());
			reqList.forEach(req -> {
				// 去除实验室管理员
				if (!req.getLabMemberId().equals(adminMember.getId())) {
					labMemberIdAll.add(req.getLabMemberId());
					if (req.getIsOpen() == 1) {
						labMemberIdOpen.add(req.getLabMemberId());
					}
				}
			});
			
			// 1、去除相关人员该权限
			if (labMemberIdAll.size() > 0) {
				this.deleteBatch(power, userInfo.getLabId(), labMemberIdAll);
			}
			// 2、添加相关人员该权限
			if (labMemberIdOpen.size() > 0) {
				this.addBatch(power, userInfo.getLabId(), labMemberIdOpen);
			}
		}
		return true;
	}
	
	@Override
	public boolean deleteBatch(String power, Long labId, List<Long> labMemberIds) {
		LambdaQueryWrapper<LabMemberPower> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(LabMemberPower::getPower, power);
		wrapper.eq(LabMemberPower::getLabId, labId);
		wrapper.in(LabMemberPower::getLabMemberId, labMemberIds);
		int b = labMemberPowerMapper.delete(wrapper);
		return b > 0;
	}
	
	@Override
	public boolean addBatch(String power, Long labId, List<Long> labMemberIds) {
		int b = labMemberPowerMapper.addBatch(power, labId, labMemberIds);
		return b > 0;
	}

	@Override
	public boolean isPower(Long labId,Long labMemberId, Power power) {
		LambdaQueryWrapper<LabMemberPower> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(LabMemberPower::getLabMemberId, labMemberId);
		wrapper.eq(LabMemberPower::getLabId,labId);
		wrapper.eq(LabMemberPower::getPower, power.getValue());
		LabMemberPower memberPower = labMemberPowerMapper.selectOne(wrapper);
		return memberPower!=null;
	}

    @Override
    public List<LabMemberPower> selectListByLabIdInLabMemberIds(Long labId,List<Long> labMemberIds) {
		Assert.notNull(labId,"labId can not be null!");
		Assert.isTrue(labMemberIds!=null && labMemberIds.size()>0,"labMemberIds can not be null or empty!");
        return labMemberPowerMapper.selectList(
        		new LambdaQueryWrapper<LabMemberPower>()
						.eq(LabMemberPower::getLabId,labId)
						.in(LabMemberPower::getLabMemberId,labMemberIds));
    }

	@Override
	public List<LabMemberPower> selectListByLabIdAndLabMemberId(Long labId,Long labMemberId) {
		return labMemberPowerMapper.selectList(
				new LambdaQueryWrapper<LabMemberPower>()
						.eq(LabMemberPower::getLabId,labId)
						.eq(LabMemberPower::getLabMemberId,labMemberId)
		);
	}

}
